package com.hb.B_面向对象.A_类与继承

/**
 * 委托也可以代替多继承来解决类似的问题。委托是一种特殊的类型，用于方法事件的委托，
 * 比如你调用A类的methodA方法，其实背后是B类的methodA去执行。在kotlin中实现委托
 * 只需要通过by关键字就可以实现委托的效果。比如我们之前提到过的by lazy语法，其实就是
 * 利用委托实现延迟初始化的语法。
 */
fun main() {
    val flyer3 = Flyer3()
    val animal3 = Animal3()
    val bird7 = Bird7(flyer3, animal3)
    bird7.eat()
}
/**
 * 如何通过委托来代替多继承是实现需求。
 *
 * */
interface CanFly{
    fun fly()
}
interface CanEat{
    fun eat()
}
open class Flyer3:CanFly{
    override fun fly() {
        println("Flyer3 fly")
    }
}
open class Animal3:CanEat{
    override fun eat() {
        println("Animal3 can eat")
    }
}

/**
 * 可以理解为 被委托的方法都可以被调用。
 *
 * 委托的方式和接口实现多继承的方式很相似，委托的优势：
 *  1. 前面说到的接口是无状态的，所以即使它提供了默认方法的实现也是很简单的，不能实现复杂的逻辑，
 *  也不推荐在接口中实现复杂的方法逻辑。我们可以利用上面委托的方式，虽然也是接口的委托，但他是用一个
 *  具体的类去实现方法的逻辑，可以拥有更强大的能力。
 *
 *  2. 假设我们需要继承的类是A，委托对象是B、C、我们在具体掉用的时候并不是像组合一样A.B.method,
 *  而是可以直接调用A.method，这更能表达A拥有该method的能力，更加直观。虽然背后也是通过委托对象
 *  来执行具体的方法逻辑的。
 *
 */
class Bird7(fly3: Flyer3,animal3: Animal3):CanFly by fly3,CanEat by animal3{}